home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / make-367.lha / make-3.67 / ar.c < prev    next >
C/C++ Source or Header  |  1993-04-29  |  4KB  |  179 lines

  1. /* Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993
  2.     Free Software Foundation, Inc.
  3. This file is part of GNU Make.
  4.  
  5. GNU Make is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. GNU Make is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with GNU Make; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "make.h"
  20. #include "file.h"
  21.  
  22. #ifndef    NO_ARCHIVES
  23.  
  24. /* Defined in arscan.c.  */
  25. extern long int ar_scan ();
  26. extern int ar_member_touch ();
  27. extern int ar_name_equal ();
  28.  
  29.  
  30. /* Return nonzero if NAME is an archive-member reference, zero if not.
  31.    An archive-member reference is a name like `lib(member)'.
  32.    If a name like `lib((entry))' is used, a fatal error is signaled at
  33.    the attempt to use this unsupported feature.  */
  34.  
  35. int
  36. ar_name (name)
  37.      char *name;
  38. {
  39.   char *p = index (name, '('), *end = name + strlen (name) - 1;
  40.   
  41.   if (p == 0 || p == name || *end != ')')
  42.     return 0;
  43.  
  44.   if (p[1] == '(' && end[-1] == ')')
  45.     fatal ("attempt to use unsupported feature: `%s'", name);
  46.  
  47.   return 1;
  48. }
  49.  
  50.  
  51. /* Parse the archive-member reference NAME into the archive and member names.
  52.    Put the malloc'd archive name in *ARNAME_P if ARNAME_P is non-nil;
  53.    put the malloc'd member name in *MEMNAME_P if MEMNAME_P is non-nil.  */
  54.  
  55. void
  56. ar_parse_name (name, arname_p, memname_p)
  57.      char *name, **arname_p, **memname_p;
  58. {
  59.   char *p = index (name, '('), *end = name + strlen (name) - 1;
  60.  
  61.   if (arname_p != 0)
  62.     *arname_p = savestring (name, p - name);
  63.  
  64.   if (memname_p != 0)
  65.     *memname_p = savestring (p + 1, end - (p + 1));
  66. }  
  67.  
  68. static long int ar_member_date_1 ();
  69.  
  70. /* Return the modtime of NAME.  */
  71.  
  72. time_t
  73. ar_member_date (name)
  74.      char *name;
  75. {
  76.   char *arname;
  77.   int arname_used = 0;
  78.   char *memname;
  79.   long int val;
  80.  
  81.   ar_parse_name (name, &arname, &memname);
  82.  
  83.   /* Make sure we know the modtime of the archive itself because
  84.      we are likely to be called just before commands to remake a
  85.      member are run, and they will change the archive itself.  */
  86.   {
  87.     struct file *arfile;
  88.     arfile = lookup_file (arname);
  89.     if (arfile == 0)
  90.       {
  91.     arfile = enter_file (arname);
  92.     arname_used = 1;
  93.       }
  94.  
  95.     (void) f_mtime (arfile, 0);
  96.   }
  97.  
  98.   val = ar_scan (arname, ar_member_date_1, (long int) memname);
  99.  
  100.   if (!arname_used)
  101.     free (arname);
  102.   free (memname);
  103.  
  104.   return (val <= 0 ? (time_t) -1 : (time_t) val);
  105. }
  106.  
  107. /* This function is called by `ar_scan' to find which member to look at.  */
  108.  
  109. /* ARGSUSED */
  110. static long int
  111. ar_member_date_1 (desc, mem, truncated,
  112.           hdrpos, datapos, size, date, uid, gid, mode, name)
  113.      int desc;
  114.      char *mem;
  115.      int truncated;
  116.      long int hdrpos, datapos, size, date;
  117.      int uid, gid, mode;
  118.      char *name;
  119. {
  120.   return ar_name_equal (name, mem, truncated) ? date : 0;
  121. }
  122.  
  123. /* Set the archive-member NAME's modtime to now.  */
  124.  
  125. int
  126. ar_touch (name)
  127.      char *name;
  128. {
  129.   char *arname, *memname;
  130.   int arname_used = 0;
  131.   register int val;
  132.  
  133.   ar_parse_name (name, &arname, &memname);
  134.  
  135.   /* Make sure we know the modtime of the archive itself before we
  136.      touch the member, since this will change the archive itself.  */
  137.   {
  138.     struct file *arfile;
  139.     arfile = lookup_file (arname);
  140.     if (arfile == 0)
  141.       {
  142.     arfile = enter_file (arname);
  143.     arname_used = 1;
  144.       }
  145.  
  146.     (void) f_mtime (arfile, 0);
  147.   }
  148.  
  149.   val = 1;
  150.   switch (ar_member_touch (arname, memname))
  151.     {
  152.     case -1:
  153.       error ("touch: Archive `%s' does not exist", arname);
  154.       break;
  155.     case -2:
  156.       error ("touch: `%s' is not a valid archive", arname);
  157.       break;
  158.     case -3:
  159.       perror_with_name ("touch: ", arname);
  160.       break;
  161.     case 1:
  162.       error ("touch: Member `%s' does not exist in `%s'", memname, arname);
  163.       break;
  164.     case 0:
  165.       val = 0;
  166.       break;
  167.     default:
  168.       error ("touch: Bad return code from ar_member_touch on `%s'", name);
  169.     }
  170.  
  171.   if (!arname_used)
  172.     free (arname);
  173.   free (memname);
  174.  
  175.   return val;
  176. }
  177.  
  178. #endif
  179.